﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using XmlMerge.Interfaces;

namespace DataSetMerge.DataTableOperators
{
    public class WixXmlTableOperator : IXmlOperator
    {

        public bool RemoveDuplicateEntries(XElement target, XElement source)
        {
            XNamespace ns = target.Name.Namespace;
            var targetelms = target.Descendants( ns + "Component");
            var sourcelms = source.Descendants(ns + "Component");

            var rems = (from t in targetelms
                        where (from s in sourcelms.Descendants(ns + "File")
                               select s.Attribute("Source").Value)
                               .Contains(t.Descendants(ns + "File").First().Attribute("Source").Value)
                        select t).ToList();

            foreach(var rem in rems)
            {
                rem.Remove();
            }

            return true;
        }

        public bool RemoveChildlessEntries(XElement target)
        {
            XNamespace ns = target.Name.Namespace;
            var targetelms = target.Descendants(ns + "Component");

            var rems = (from i in targetelms
                        where i.Descendants().Count() == 0
                        select i).ToList();

            foreach(var rem in rems)
            {
                rem.Remove();
            }

            return true;
        }


        public bool AddNewEntries(XElement target, XElement source)
        {
            XNamespace ns = target.Name.Namespace;
            var comps = source.Descendants(ns + "Component");

            foreach(XElement comp in comps)
            {
                var targcomp = target.Descendants(ns +"Component");
                targcomp.First().Parent.Add(comp);

                var groupcomp = target.Descendants(ns + "ComponentGroup");
                if (groupcomp.Count() > 0)
                {
                    groupcomp.First().Add(new XElement(ns + "ComponentRef",
                        new XAttribute("Id", comp.Attribute("Id").Value)));
                }
            }

            return true;
        }

        public bool RemoveSubtractedEntries(XElement target, XElement source)
        {
            XNamespace ns = target.Name.Namespace;
            var trgfiles = target.Descendants(ns + "File");
            var sourcelms = source.Descendants(ns + "File");

            var rems = (from i in trgfiles
                        where !(from r in sourcelms
                                select r.Attribute("Source").Value)
                                .Contains(i.Attribute("Source").Value)
                        select i).ToList();


            foreach(var rem in rems)
            {
                var refcomp = (from i in target.Descendants(ns + "ComponentRef")
                               where i.Attribute("Id").Value == rem.Parent.Attribute("Id").Value
                               select i).Single();

                refcomp.Remove();
                rem.Remove();
            }

            return true;
        }
    }
}
